//
// Created by kode.zhong on 2021/3/6.
//

#ifndef LOX_VM_LOX_CHUNK_H_
#define LOX_VM_LOX_CHUNK_H_

#include <vector>
#include <memory>

#include "common/common.h"

namespace lox {

/**
 * Define operation for VM.
 */
enum OpCode {
  OP_CONSTANTS,
  OP_ADD,
  OP_SUBTRACT,
  OP_MULTIPLY,
  OP_DIVIDE,
  OP_NEGATE,
  OP_RETURN
};

/**
 * Chunk contains opcodes.
 * We use vector instead of uint8_t*, capacity and count.
 */
template<class VALUE_TYPE=double>
class Chunk {
 public:
  void WriteChunk(Byte op_code, size_t line = 0);
  size_t Size() const;
  std::vector<size_t> GetLines() const;
  // Return added constant index
  size_t AddConstants(const VALUE_TYPE& value);
  VALUE_TYPE GetValue(size_t idx) const;

  ByteCodes m_code;

  // Constants pool, use vector instead of struct which contains raw pointer
  ValueArray<VALUE_TYPE> m_values;

  // Record lines
  std::vector<size_t> m_lines;
};

template <typename T>
using ChunkPtr = std::shared_ptr<Chunk<T>>;


}

#endif //LOX_VM_LOX_CHUNK_H_
